package com.hsxc.cdz.controller.consoleController;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.json.JSONException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.hsxc.cdz.base.bean.ConsoleUser;
import com.hsxc.cdz.base.bean.Pile;
import com.hsxc.cdz.base.util.TimeFormatter;
import com.hsxc.cdz.mgmt.GlobalManager;
import com.hsxc.cdz.mgmt.pile.PileManager;
import com.hsxc.cdz.mgmt.station.StationManager;
import com.hsxc.cdz.mgmt.user.UserManager;
import com.hsxc.cdz.monitor.FSM.CachePile;

import net.sf.json.JSONObject;

/**
 * @author 陈钊
 * @version 创建时间：2016年5月30日 下午3:31:48 类说明：
 */
@Controller
@RequestMapping("/api")
public class PileController {
    protected static Logger log = LoggerFactory.getLogger(PileController.class);
    // ===========================================================================================================
    // 注入service实例对象
    @Autowired
    private PileManager pileRegister;
    @Autowired
    StationManager stationmanager;
    @Autowired
    UserManager userManager;

    // ==========================================================================================================
    // 类私有常量
    private static final int SUCCESS = 0; // 请求成功
    private static final int ERR_DATA = 1; // 参数错误
    private static final int ERR_DEVICE = 2; // 设备信息有误
    private static final int FAILURE = 3; // 处理失败
    private static final int ERR_ADDRESS = 4; // 地址冲突

    // ==========================================================================================================
    // 处理请求，获取所有电桩信息
    @RequestMapping(value = "/piles", method = RequestMethod.GET)
    @ResponseBody
    public Object getChargePiles(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
                                 HttpSession httpSession) {

        List<Pile> chargePiles = new ArrayList<Pile>();
        List<Pile> chargePiles_time = null;
        JSONObject resultJSONObject = new JSONObject();
        Subject user = SecurityUtils.getSubject();
        ConsoleUser consoleuser = new ConsoleUser();
        consoleuser = (ConsoleUser) httpSession.getAttribute("conuser");
        String operatorNO = consoleuser.getOperatorNO();
        String user_name = consoleuser.getUser_name();
        try {
            httpServletRequest.setCharacterEncoding("utf-8");
            httpServletResponse.setCharacterEncoding("UTF-8");
            resultJSONObject.put("success", true);
            if (user.hasRole("vendor") || user.hasRole("opDeviceManager") || user.hasRole("pileDeviceManager")) {
                log.debug("请求所有充电桩");
                chargePiles = pileRegister.getAllPile();
            }
            if (user.hasRole("operator") || user.hasRole("virtualOperator")) {
                chargePiles = pileRegister.getpileByOperatorNO(operatorNO);
            }

            if (user.hasRole("stationAdmin")) {

                List<String> stationNO = stationmanager.getStationNOByName(user_name);
                log.debug("============================" + "stationNO:" + stationNO + "============================");
                chargePiles = pileRegister.getPileByStationNO(stationNO);
            }
            if (!chargePiles.isEmpty()) {
                chargePiles_time = new ArrayList<>();
                for (Iterator<Pile> iterator = chargePiles.iterator(); iterator.hasNext(); ) {
                    Pile chargePile = iterator.next();
                    chargePile.setRegTime(TimeFormatter.getTime(chargePile.getRegTime()));
                    chargePile.setLogoutTime(TimeFormatter.getTime(chargePile.getLogoutTime()));
                    chargePiles_time.add(chargePile);
                }

                resultJSONObject.put("data", chargePiles_time);
            } else {
                resultJSONObject.put("data", new ArrayList<>());
            }

        } catch (Exception e) {
            e.printStackTrace();
            log.info("message" + e.getMessage());
            return resultJSONObject;
        }
        log.debug("======================" + resultJSONObject.toString() + "==========================");
        return resultJSONObject;
    }

    // =======================================================================================================================
    @RequestMapping(value = "/piles", method = RequestMethod.POST)
    @ResponseBody
    public Object addPile(@RequestBody String json, HttpServletRequest httpServletRequest, HttpSession httpSession) {
        JSONObject result = new JSONObject();
        result.put("success", true);
        Subject user = SecurityUtils.getSubject();
        ConsoleUser parentUser = (ConsoleUser) httpSession.getAttribute("conuser");
        Pile pile = new Pile();
        org.json.JSONObject jsonObject;
        try {
            jsonObject = new org.json.JSONObject(json);
            pile.setAccount(jsonObject.getString("account").trim());
            pile.setDelete(false);
            if (user.hasRole("vendor") || user.hasRole("operator")) {
                log.debug(parentUser.getOperatorNO());
                pile.setOperatorNO(parentUser.getOperatorNO());
            }
            if (user.hasRole("stationAdmin")) {
                ConsoleUser lastUser = userManager.loadConUserBySsid(parentUser.getSsid());
                pile.setOperatorNO(lastUser.getOperatorNO());
            }
            pile.setPassword(jsonObject.getString("password").trim());
            pile.setPileNO(jsonObject.getString("pileNO").trim());
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
            pile.setRegTime(sdf.format(new Date()));
            pile.setState(Pile.STATE_NOREGISTER);
            String stationNO = jsonObject.getString("stationNO");
            pile.setStationNO(stationNO.trim());
            pile.setOwnType(Pile.OWN_TYPE_CORP);
            pile.setPhyType(Pile.PHY_TYPE_AC); // TODO:init
        } catch (JSONException e) {
            result.put("added", false);
            result.put("errcode", ERR_DATA);
            result.put("message", "数据格式有误");
            log.info("message:" + "数据格式有误");
            return result;
        }
        if (stationmanager.selStationByNO(pile.getStationNO()) == null) {
            result.put("added", false);
            result.put("errcode", ERR_DEVICE);
            result.put("message", "充电站不存在");
            log.info("message:" + "充电站不存在");
            return result;
        }
        if (pileRegister.selPile(pile.getPileNO()) != null) {
            result.put("added", false);
            result.put("errcode", ERR_ADDRESS);
            result.put("message", "电桩编号已存在");
            log.info("message:" + "电桩编号已存在");
            return result;
        }

        int i = 0;
        if (pile != null) {
            i = pileRegister.addPileManually(pile);
        }
        if (i <= 0) {
            result.put("added", false);
            result.put("errcode", FAILURE);
            result.put("message", "设备注册失败");
            log.debug("message:" + "设备注册失败");
        } else {
            result.put("added", true);
            result.put("errcode", SUCCESS);
            result.put("message", "设备注册成功");
            log.info("message:" + "设备注册成功");
        }
        return result;
    }

    // =================================================================================================================
    @RequestMapping(value = "/piles", method = RequestMethod.PUT)
    @ResponseBody
    public Object updatePile(@RequestBody String data, HttpSession httpSession) {
        org.json.JSONObject json = null;
        JSONObject result = new JSONObject();
        //ConsoleUser parentUser = (ConsoleUser) httpSession.getAttribute("conuser");
        try {
            json = new org.json.JSONObject(data);
            result.put("success", true);
        } catch (JSONException e) {
            e.printStackTrace();
            result.put("success", false);
            log.info("message:" + e.getMessage());
            return result;
        }
        log.debug("=============================" + "收到的数据" + data + "===================================");

        Pile pile = new Pile();
        try {
            String stationNO = json.getString("stationNO");
            pile.setStationNO(stationNO);
            String pileNo = json.getString("pileNO");
            pile.setPileNO(pileNo);
            String account = json.getString("account");
            pile.setAccount(account);
            String password = json.getString("password");
            pile.setPassword(password);
            result.put("added", true);
        } catch (JSONException e) {
            e.printStackTrace();
            log.info("message:" + e.getMessage());
            result.put("added", false);
        }
        log.debug("==============================" + pileRegister.updatePileByPage(pile) + "=========================");
        return result;
    }

    // ============================================================================================================
    @RequestMapping(value = "/piles/{pileNO}", method = RequestMethod.DELETE)
    @ResponseBody
    public Object deletePile(@PathVariable("pileNO") String pileNO) {
        log.info("ENTER CONTROLLER DELETE PILE");
        log.info("PILENO" + pileNO);
        JSONObject json = new JSONObject();
        json.put("success", true);
        if (pileNO == null) {
            json.put("added", false);
            json.put("errcode", ERR_DATA);
            json.put("message", "桩数据有误");
            log.info("message" + "桩数据有误");
            return json;
        }

        int i = pileRegister.delPileManually(pileNO);
        if (i == 0) {
            json.put("added", false);
            json.put("errcode", ERR_DEVICE);
            json.put("message", "不存在该桩");
            log.info("message:" + "不存在该桩");
            return json;
        }
        json.put("added", true);
        return json;
    }

    // 获取特定充电站的电桩
    // ===============================================================================================================
    @RequestMapping(value = "/pilesByNO", method = RequestMethod.GET)
    @ResponseBody
    public Object getPilesByNO(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
                               HttpSession httpSession) {
        List<Pile> chargePiles = new ArrayList<Pile>();
        List<Pile> chargePiles_time = null;
        JSONObject resultJSONObject = new JSONObject();
        try {
            String stationNO = httpServletRequest.getParameter("stationno");
            chargePiles = pileRegister.getpileByStation(stationNO);
            resultJSONObject.put("success", true);
            if (!chargePiles.isEmpty()) {
                chargePiles_time = new ArrayList<>();
                for (Iterator<Pile> iterator = chargePiles.iterator(); iterator.hasNext(); ) {
                    Pile chargePile = iterator.next();
                    chargePile.setRegTime(TimeFormatter.getTime(chargePile.getRegTime()));
                    chargePile.setLogoutTime(TimeFormatter.getTime(chargePile.getLogoutTime()));
                    chargePiles_time.add(chargePile);
                }

                resultJSONObject.put("data", chargePiles_time);
            } else {
                resultJSONObject.put("data", new ArrayList<>());
            }

        } catch (Exception e) {
            e.printStackTrace();
            return resultJSONObject;
        }
        log.debug(
                "======================================" + resultJSONObject.toString() + "==========================");
        return resultJSONObject;

    }

    // =========================================================================================================================
    @RequestMapping(value = "/piles/reboot", method = RequestMethod.GET)
    @ResponseBody
    public Object rebootPile(@RequestParam("pileNo") String pileNo) {
        CachePile pile;
        JSONObject result = new JSONObject();
        result.put("success", true);
        if (pileNo == null) {
            result.put("added", false);
            result.put("errcode", ERR_DATA);
            result.put("message", "桩数据有误");
            log.info("message:" + "桩数据有误");
            return result;
        }
        pile = GlobalManager.pileManager.getPile(pileNo);
        if (pile == null) {
            result.put("added", false);
            result.put("errcode", ERR_DEVICE);
            result.put("message", "不存在该桩");
            log.info("message:" + "不存在该桩");
            return result;
        }
        int i = pile.reboot();
        if (i == 1) {
            result.put("added", false);
            result.put("errcode", FAILURE);
            result.put("message", "重启失败");
            log.info("message:" + "重启失败");
            return result;
        }
        result.put("added", true);
        log.debug("重启桩返回:" + result);
        return result;
    }

    // ===================================================================================================================
    @RequestMapping(value = "/piles/lock", method = RequestMethod.GET)
    @ResponseBody
    public Object lock(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
        String pileNo = httpServletRequest.getParameter("pileNo");
        if (pileNo == null) {
            return getResult(ERR_DATA, "电桩编号有误");
        }
        CachePile pile = GlobalManager.pileManager.getPile(pileNo);
        if (pile == null) {
            return getResult(ERR_DATA, "未找到该桩");
        }
        int i = pile.lock();
        if (i == 0) {
            return getResult(SUCCESS, "锁桩成功");
        }

        return getResult(FAILURE, "锁桩失败");
    }

    // ==========================================================================================================
    @RequestMapping(value = "/piles/unlock", method = RequestMethod.GET)
    @ResponseBody
    public Object unlock(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
        String pileNo = httpServletRequest.getParameter("pileNo");
        if (pileNo == null) {
            return getResult(ERR_DATA, "电桩编号有误");
        }
        CachePile pile = GlobalManager.pileManager.getPile(pileNo);
        if (pile == null) {
            return getResult(ERR_DATA, "未找到该桩");
        }
        int i = pile.unlock();
        if (i == 0) {
            return getResult(SUCCESS, "解锁成功");
        }
        return getResult(FAILURE, "解锁失败");
    }

    // 获取一个充电桩的详细信息
    // ==========================================================================================================
    @RequestMapping(value = "/piles/detail", method = RequestMethod.GET)
    @ResponseBody
    public Object getDetail(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
        JSONObject result = new JSONObject();
        String pileNo = httpServletRequest.getParameter("pileNo");
        if (pileNo == null || pileNo == "") {
            result.put("success", false);
            return getResult(ERR_DATA, "电桩编号有误");
        }

        CachePile pile = GlobalManager.pileManager.getPile(pileNo);
        JSONObject data = new JSONObject();
        // 离线或未注册或故障
        if (pile == null) {
            data.put("voltage", 0);
            data.put("current", 0);
            data.put("power", 0);
            data.put("hours", 0);
            data.put("minutes", 0);
            data.put("fault", "00");
            data.put("inserted", false);
            data.put("reserve", false);
            data.put("electricity", 0);
            data.put("money", 0);
        }
        // 设备在线，返回真实数据
        else {
            data.put("voltage", pile.getVoltage());
            data.put("current", pile.getCurrent());
            data.put("power", pile.getPower());
            data.put("hours", pile.getHours());
            data.put("minutes", pile.getMinutes());
            data.put("fault", pile.getFault());
            data.put("inserted", pile.isInserted());
            data.put("reserve", pile.getReserve());
            data.put("electricity", pile.getElectricity());
            data.put("money", pile.getMoney());
        }
        result.put("data", data);
        result.put("success", true);
        return result;
    }

    public JSONObject getResult(int errcode, String message) {
        JSONObject result = new JSONObject();
        result.put("success", true);
        if (errcode == SUCCESS) {
            result.put("added", true);
        } else {
            result.put("added", false);
        }
        result.put("errcode", errcode);
        result.put("message", message);
        return result;
    }

    @RequestMapping(value = "/piles/setRate", method = RequestMethod.POST)
    @ResponseBody
    public Object setPileFeeRate(@RequestBody String jsonParams) {

        JSONObject params = JSONObject.fromObject(jsonParams);
        double oneRate = 1;
        double twoRate = 1;
        double threeRate = 1;
        double fourRate = 1;
        double serviceFee = 1;
        String timeRate = null;
        String pileNo = null;
        if (params.has("oneRate"))
            oneRate = params.getDouble("oneRate");
        if (params.has("twoRate"))
            twoRate = params.getDouble("twoRate");
        if (params.has("threeRate"))
            threeRate = params.getDouble("threeRate");
        if (params.has("fourRate"))
            fourRate = params.getDouble("fourRate");
        if (params.has("serviceFee"))
            serviceFee = params.getDouble("serviceFee");
        if (params.has("timeRate"))
            timeRate = params.getString("timeRate").trim();
        if (params.has("pileNo"))
            pileNo = params.getString("pileNo").trim();
        JSONObject result = new JSONObject();
        result.put("success", true);

        Subject subject = SecurityUtils.getSubject();
        ConsoleUser consoleUser = consoleUser = GlobalManager.consoleUserManager.loadConUserByName(subject.getPrincipal().toString());
        String operatorNo = null;
        //参数pileNo为空时表示批量处理
        if (pileNo == null) {
            List<String> errorList = new ArrayList<>();
            //更新缓存
            List<CachePile> cachePiles = GlobalManager.pileManager.getAllCachePile();
            if(cachePiles==null||cachePiles.size()==0){
                result.put("errcode", 1);
                result.put("message", "没有桩");
                return result;
            }
            for (Iterator<CachePile> iterator = cachePiles.iterator(); iterator.hasNext(); ) {
                //更新数据库
                CachePile pile = iterator.next();
                Pile pileTrue = GlobalManager.pileRegister.selPile(pile.getAddress());
                //设置费率属性
                pileTrue.setOneRate((int) (oneRate * 100));
                pileTrue.setTwoRate((int) (twoRate * 100));
                pileTrue.setThreeRate((int) (threeRate * 100));
                pileTrue.setFourRate((int) (fourRate * 100));
                pileTrue.setServiceFee((int) (serviceFee * 100));
                pileTrue.setTimeRate(timeRate);
                if (subject.hasRole("vendor") || subject.hasRole("operator")) {
                    operatorNo = consoleUser.getOperatorNO();
                    pileTrue.setOperatorNO(operatorNo);
                } else if (subject.hasRole("stationAdmin")) {
                    ConsoleUser parentSubject = GlobalManager.consoleUserManager.loadConUserBySsid(consoleUser.getSsid());
                    operatorNo = parentSubject.getOperatorNO();
                    pileTrue.setOperatorNO(operatorNo);
                } else {
                    result.put("errcode", 2);
                    result.put("message", "您没有操作权限");
                    return result;
                }
                GlobalManager.pileRegister.updatePile(pileTrue);
                //发送设置费率指令
                if (pile.getOperator().equals(operatorNo)) {
                    int i = pile.rateSetting(oneRate, twoRate, threeRate, fourRate, serviceFee, timeRate);
                    if (i != 0) {
                        errorList.add(pile.getAddress());
                    }
                }
            }
            if (errorList == null || errorList.size() != 0) {
                result.put("errcode", 3);
                result.put("message", "有设置不成功");
                result.put("data", errorList);
                return result;
            } else {
                result.put("errcode", 0);

                return result;
            }

        }
        //pileNo非空则是单个桩设置
        else {
            CachePile pile = GlobalManager.pileManager.getPile(pileNo);
            if (pile == null) {
                result.put("added", false);
                result.put("errcode", 4);
                result.put("message", "桩不在线");
                log.info("message:" + "桩不在线");
                return result;
            }

            //更新数据库
            Pile pileTrue = GlobalManager.pileRegister.selPile(pileNo);
            //设置费率属性
            pileTrue.setOneRate((int) (oneRate * 100));
            pileTrue.setTwoRate((int) (twoRate * 100));
            pileTrue.setThreeRate((int) (threeRate * 100));
            pileTrue.setFourRate((int) (fourRate * 100));
            pileTrue.setServiceFee((int) (serviceFee * 100));

            pileTrue.setTimeRate(timeRate);
            GlobalManager.pileRegister.updatePile(pileTrue);

            int i = pile.rateSetting(oneRate, twoRate, threeRate, fourRate, serviceFee, timeRate);
            if (i == 1) {
                result.put("added", false);
                result.put("errcode", FAILURE);
                result.put("message", "费率设置失败");
                log.info("message:" + "费率设置失败");
                return result;
            } else {
                result.put("errcode", SUCCESS);
                Pile pile1 = GlobalManager.pileRegister.selPile(pileNo);
                result.put("data", pile1);
                result.put("added", true);
                log.debug("设置费率返回:" + result);
                return result;
            }
        }
    }

    @RequestMapping(value = "/piles/getRate", method = RequestMethod.POST)
    @ResponseBody
    public Object getPileFeeRate(@RequestBody String jsonParams) {
        JSONObject params = JSONObject.fromObject(jsonParams);
        String pileNo = null;
        if (params.has("pileNo")) {
            pileNo = params.getString("pileNo");
        }
        JSONObject result = new JSONObject();
        result.put("success", true);
        Pile pile = pileRegister.selPile(pileNo);
        if (pile != null && pile.getState() == Pile.STATE_IDLE) {
            result.put("errcode", 0);
            result.put("data", pile);
            return result;
        }
        result.put("errcode", 1);
        result.put("message", "桩不在线");
        return result;
    }
}
